//
// Created by wxd on 2025/9/11.
//
#pragma once

#ifndef OBJECT_H
#define OBJECT_H

#include "IObject.h"
#include "../global/generator_id.h"
#include "glm/glm.hpp"
#include "glm/ext/matrix_transform.hpp"
#include <vector>

class Object : public IObject {
public:
    Object() {
        mTraceId = IDGenerator::getInstance().generateRaw();
    }

    explicit Object(const ObjectType type) : mType(type) {
        mTraceId = IDGenerator::getInstance().generateRaw();
    }

    explicit Object(const ObjectType type, const std::string& name) : mObjName(name), mType(type) {
        mTraceId = IDGenerator::getInstance().generateRaw();
    }

    ~Object() override = default;

    std::string getTraceId() override { return mTraceId; }

    std::string getName() const override { return mObjName; }

    ObjectType getType() override { return mType; }

    glm::mat4 getModelMatrix() override;

    glm::vec3 getScale() const { return mScale; }
    glm::vec3 getRotation() const { return mRotation; }
    glm::vec3 getPosition() const { return mPosition; }

    void setScale(glm::vec3 scale) { mScale = scale; }
    void setScaleX(float x) { mScale.x = x; }
    void setScaleY(float y) { mScale.y = y; }
    void setScaleZ(float z) { mScale.z = z; }

    void setRot(glm::vec3 rotation) { mRotation = rotation; }
    void setRotX(float x) { mRotation.x = x; }
    void setRotY(float y) { mRotation.y = y; }
    void setRotZ(float z) { mRotation.z = z; }
    void setRotAccX(float accX) { mRotation.x += accX; }
    void setRotACcY(float accY) { mRotation.y += accY; }
    void setRotAccZ(float accZ) { mRotation.z += accZ; }

    void setPos(glm::vec3 position) { mPosition = position; }
    void setPosX(float x) { mPosition.x = x; }
    void setPosY(float y) { mPosition.y = y; }
    void setPosZ(float z) { mPosition.z = z; }
    void setPosAccX(float accX) { mPosition.x += accX; }
    void setPosAccY(float accY) { mPosition.y += accY; }
    void setPosAccZ(float accZ) { mPosition.z += accZ; }

    void setName(const std::string& name) { mObjName = name; }

    void addChild(Object* child);
    std::vector<Object*> getChilds() const;
    Object* getParent() const;

protected:

    std::string mTraceId;
    std::string mObjName { "Object" };
    ObjectType mType { ObjectType::OBJECT };
    glm::mat4 mModelMatrix { glm::mat4(1.f) };

    // 几何相关的参数
    glm::vec3 mScale { glm::vec3(1.f) };
    glm::vec3 mPosition { glm::vec3(0.f) };
    glm::vec3 mRotation { glm::vec3(0.f) };

    Object* mParent { nullptr };     // 记录当前Obj的父亲节点
    std::vector<Object*> mChilds;    // 记录当前Obj的所有孩子节点
};

#endif //OBJECT_H
